#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "test.h"

/*
 * hoot inline
 *
 * hook其他位置的函数，或者在任意位置插入hook
 */

void sevenWeapons(int number)
{
    char* str = "Hello,ac!";
    printf("%s %d\n", str, number);
}

int hook_direct(struct hook_t *h, unsigned int addr, void *hookf)
{
    int i;

    printf("addr  = %x\n", addr);
    printf("hookf = %x\n", (unsigned int)hookf);

//mprotect
    /* (1) 解除被hook位置的写保护 */
    mprotect((void*)0x8000, 0xa000-0x8000, PROT_READ|PROT_WRITE|PROT_EXEC);

//modify function entry 
    /* (2) hook */
    h->patch = (unsigned int)hookf;
    h->orig = addr;
    /* (2.1) 构造跳转指令 */
    h->jump[0] = 0xe59ff000; // LDR pc, [pc, #0]
    h->jump[1] = h->patch;
    h->jump[2] = h->patch;
    /* (2.2) 备份hook点的原指令 */
    for (i = 0; i < 3; i++)
        h->store[i] = ((int*)h->orig)[i];
    /* (2.3) 替换hook点为新的跳转指令 */
    for (i = 0; i < 3; i++)
        ((int*)h->orig)[i] = h->jump[i];

//cacheflush    
    /* (3) 刷新cache */
    hook_cacheflush((unsigned int)h->orig, (unsigned int)h->orig+sizeof(h->jump));
    return 1;
}

void  __attribute__ ((noinline)) my_sevenWeapons(int number)
{
    /* (1) hook函数的自定义操作 */
    printf("sevenWeapons() called, number = %d\n", number);
    number++;

    void (*orig_sevenWeapons)(int number);
    orig_sevenWeapons = (void*)eph.orig;

    /* (2) 处理完hook上的新操作
          继续兼任的处理旧的操作
     */
    /* (2.1) 把hook点恢复成原指令 */
    hook_precall(&eph);
    /* (2.2) 调用原函数 */
    orig_sevenWeapons(number);
    /* (2.3) 如果需要下一次hook，继续把hook点替换成跳转到新函数
            和hook_direct()函数一样
     */
    hook_postcall(&eph);

}

void hook_precall(struct hook_t *h)
{
    int i;
    /* (2.1.1) 把hook点恢复成原指令 */
    for (i = 0; i < 3; i++)
        ((int*)h->orig)[i] = h->store[i];

    hook_cacheflush((unsigned int)h->orig, (unsigned int)h->orig+sizeof(h->jump)*10);
}



int main()
{
    while (1) {
        sleep(1);
    }
    return 0;
}

#if 0

gcc -o hook-exe hook-exe.c -no-pie



#endif
